//package org.example.config;
//
//import org.example.validate.MyAccessVoter;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.security.access.AccessDecisionManager;
//import org.springframework.security.access.AccessDecisionVoter;
//import org.springframework.security.access.AccessDeniedException;
//import org.springframework.security.access.ConfigAttribute;
//import org.springframework.security.access.vote.AbstractAccessDecisionManager;
//import org.springframework.security.authentication.InsufficientAuthenticationException;
//import org.springframework.security.core.Authentication;
//import java.util.ArrayList;
//import java.util.Collection;
//import java.util.List;
//
///**
// * @author ccx
// * @version V1.0
// * @Package org.example.config
// * @date 2020/4/10 22:11
// */
//@Configuration
//public class AccessDecisionManagerConfig {
//
//    /**
//     * AffirmativeBased 一票通过，只要有一个投票器通过就允许访问
//     * ConsensusBased 有一半以上投票器通过才允许访问资源
//     * UnanimousBased 所有投票器都通过才允许访问
//     *
//     * 一个资源的权限控制 一个是方法的权限控制 它们不同享同一个AccessDecisionManager 。 继承GlobalMethodSecurityConfiguration 重写其中的方法
//     * @return
//     */
//    @Bean
//    public AccessDecisionManager accessDecisionManager(){
//        List<AccessDecisionVoter<?>> decisionVoters = new ArrayList<>();
//        //允许我们使用 SpEL (Spring Expression Language) 去授权使用@PreAuthorize注解的请求.
////        decisionVoters.add(new WebExpressionVoter());
////        // 基于任何一个以“ROLE_”开头的配置属性进行投票. 如果符合条件，则搜索认证对象的GrantedAuthority列表.
////        decisionVoters.add(new RoleVoter());
////        // 根据认证对象的级别进行投票，具体查询完整认证用户、记住我认证或匿名认证.
////        decisionVoters.add(new AuthenticatedVoter());
//        // 自定义投票器
//        decisionVoters.add(new MyAccessVoter());
//        return new MyAccessDecisionManager(decisionVoters);
//    }
//
//    class MyAccessDecisionManager extends AbstractAccessDecisionManager {
//
//        protected MyAccessDecisionManager(List<AccessDecisionVoter<?>> decisionVoters) {
//            super(decisionVoters);
//        }
//
//        @Override
//        public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
//            int deny = 0;
//
//            for (AccessDecisionVoter voter : getDecisionVoters()) {
//                int result = voter.vote(authentication, object, configAttributes);
//
//                if (logger.isDebugEnabled()) {
//                    logger.debug("Voter: " + voter + ", returned: " + result);
//                }
//
//                switch (result) {
//                    case AccessDecisionVoter.ACCESS_GRANTED:
//                        return;
//
//                    case AccessDecisionVoter.ACCESS_DENIED:
//                        deny++;
//
//                        break;
//
//                    default:
//                        break;
//                }
//            }
//
//            if (deny > 0) {
//                throw new AccessDeniedException(messages.getMessage(
//                        "AbstractAccessDecisionManager.accessDenied", "Access is denied"));
//            }
//
//            // To get this far, every AccessDecisionVoter abstained
//            checkAllowIfAllAbstainDecisions();
//        }
//
//        @Override
//        public boolean supports(ConfigAttribute attribute) {
//            return true;
//        }
//
//        @Override
//        public boolean supports(Class<?> clazz) {
//            return true;
//        }
//    }
//
//
//}
